package com.spi.soconversion.base.data;


import java.io.File;
import java.math.BigDecimal;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

import com.spi.soconversion.base.SOCException;
import com.spi.soconversion.base.definition.SOCHeaderCharge;
import com.spi.soconversion.base.definition.SOCHeaderCharges;
import com.spi.soconversion.base.definition.SOCOrder;
import com.spi.soconversion.base.definition.SOCOrderExtn;
import com.spi.soconversion.base.definition.SOCOrderLine;
import com.spi.soconversion.base.definition.SOCOrderLineCharge;
import com.spi.soconversion.base.definition.SOCOrderLineCharges;
import com.spi.soconversion.base.definition.SOCOrderLineExtn;
import com.spi.soconversion.base.definition.SOCOrderLineItem;
import com.spi.soconversion.base.definition.SOCOrderLinePriceInfo;
import com.spi.soconversion.base.definition.SOCOrderLineSalvage;
import com.spi.soconversion.base.definition.SOCOrderLineSchedule;
import com.spi.soconversion.base.definition.SOCOrderLineStatus;
import com.spi.soconversion.base.definition.SOCOrderLineTax;
import com.spi.soconversion.base.definition.SOCOrderLineTaxes;
import com.spi.soconversion.base.definition.SOCOrderLines;
import com.spi.soconversion.base.definition.SOCOrderNote;
import com.spi.soconversion.base.definition.SOCOrderNotes;
import com.spi.soconversion.base.definition.SOCOrderPersonalInfoBillTo;
import com.spi.soconversion.base.definition.SOCOrderPersonalInfoShipTo;
import com.spi.soconversion.base.definition.SOCOrderPersonalInfoSoldTo;
import com.spi.soconversion.base.definition.SOCOrderPriceInfo;
import com.spi.soconversion.base.handlers.ClosedSalesConversionStatisticsHandler;
import com.spi.soconversion.orders.SOCChargeNames;
import com.spi.soconversion.orders.SOCClosedOrderLine;
import com.spi.soconversion.orders.SOCPOSProvince;
import com.spi.soconversion.orders.conversion.CItemType;
import com.spi.soconversion.orders.conversion.ClosedOrderDeliveryMethod;
import com.spi.soconversion.orders.conversion.ClosedOrderFulfillmentType;
import com.spi.soconversion.orders.conversion.ClosedOrderLineType;
import com.spi.soconversion.orders.conversion.ClosedOrderStatus;
import com.spi.soconversion.orders.conversion.CofiToMcfLinesItemTypes;
import com.spi.soconversion.orders.conversion.InvalidItemTypes;
import com.spi.soconversion.orders.conversion.PromiseEndDate;
import com.spi.soconversion.orders.conversion.PromiseStartDate;
import com.spi.soconversion.util.ErrorConstants;
import com.spi.soconversion.util.ErrorMessageReader;
import com.spi.soconversion.util.QueryConstants;
import com.spi.soconversion.util.QueryReader;
import com.spi.soconversion.util.ResourceProvider;
import com.spi.soconversion.util.SOCConstants;
import com.spi.soconversion.util.SOCFileWriter;
import com.spi.soconversion.util.SOCUtility;

public class ClosedSalesOrderDataProcessor implements DataProcessor {
		
    static private org.apache.commons.logging.Log log = 
        org.apache.commons.logging.LogFactory.getLog(ClosedSalesOrderDataProcessor.class);

	private int d_batchSize;
	private int d_batchNum;
	private int d_totalRecProcessed;
	private String d_logFileName;
	private SOCFileWriter d_fileWriter;	
	private String d_xmlDirectory;
	private int d_xmlCounter;
	private int d_recordsFetched;
	private int d_ordersNotConverted;
	private ArrayList<Long> convertedOrdersList = new ArrayList<Long>();
	private ArrayList<Long> notConvertedOrdersList = new ArrayList<Long>();
	private ClosedSalesConversionStatisticsHandler statisticsHandler;
	
	private ResourceProvider provider;
	
	public ClosedSalesOrderDataProcessor(int batchSize, int totalRecProcessed, String logFileName, SOCFileWriter fileWriter, String xmlDirectory,int batchNum) {
		d_batchSize=batchSize;
		d_totalRecProcessed=totalRecProcessed;
		d_logFileName = logFileName;
		d_fileWriter = fileWriter;
		d_xmlDirectory = xmlDirectory;
		d_batchNum=batchNum;
		statisticsHandler= new ClosedSalesConversionStatisticsHandler(d_logFileName,d_fileWriter);
		provider = ResourceProvider.getInstance();
	}

	public int processRecords() throws SOCException  {
		int result = 0;
		PreparedStatement closedOrderStmt=null;
		long badRecords =0;
		ResultSet rsClosedOrders=null;
		
		String fetchClosedOrdersQuery = null;
		d_fileWriter.write(d_logFileName, SOCUtility.writeLogMessage(SOCConstants.MESSAGE_PROCESSING_CLOSED_ORDER_STARTS));
		int ordersFetched=0;
		
		if(d_batchSize > 0) {
 			fetchClosedOrdersQuery = QueryReader.getQuery(QueryConstants.SELECT_CLOSED_ORDERS_QUERY);
		}
		else {
			fetchClosedOrdersQuery = QueryReader.getQuery(QueryConstants.SELECT_ALL_CLOSED_ORDERS_QUERY);
		}

		try  {
			closedOrderStmt=provider.getdbConnection().prepareStatement(fetchClosedOrdersQuery);
			// Change this line when testng to create xml for particular record
			//d_totalRecProcessed=95425;		
			closedOrderStmt.setInt(1, d_totalRecProcessed+1);
			if(d_batchSize>0)
			{
				closedOrderStmt.setInt(2, d_totalRecProcessed+d_batchSize);
			}
			rsClosedOrders=closedOrderStmt.executeQuery();
			long orderNumber = -1;
			long lastOrderNumber = -1;
			ArrayList<SOCClosedOrderLine> orderLines = new ArrayList<SOCClosedOrderLine>();	
			while(rsClosedOrders.next())
			{
				SOCClosedOrderLine closedOrderLine=getOrderLine(rsClosedOrders);	
				boolean badRecord=false;				
				orderNumber =Long.parseLong(closedOrderLine.getOrderNumber());
				
				if(lastOrderNumber!=-1 && lastOrderNumber!=orderNumber)
				{
					ordersFetched++;
					log.info("processing order "+lastOrderNumber);
					processOrder(orderLines,lastOrderNumber);
					orderLines = new ArrayList<SOCClosedOrderLine>();
				}
				if(!orderLines.contains(closedOrderLine)) {
					orderLines.add(closedOrderLine);
				}				
				lastOrderNumber=orderNumber;
			}
			if(orderLines.size()>0)
			{
				log.info("processing order "+orderNumber);
				processOrder(orderLines,orderNumber);				
				ordersFetched++;
			}
			statisticsHandler.updateMessages();
			if(d_batchSize==0)
			{
				result=d_totalRecProcessed+ordersFetched;
			}
			else
			{
				result=d_totalRecProcessed+d_batchSize;
			}
			d_recordsFetched = ordersFetched;
			
			d_fileWriter.write(d_logFileName, SOCUtility.writeLogMessage(SOCConstants.MESSAGE_PROCESSING_CLOSED_ORDER_ENDS));
			
			return result;
		}
		catch (SQLException se) 
		{
			se.printStackTrace();
			d_fileWriter.write(d_logFileName, SOCUtility.writeLogMessage(ErrorMessageReader.getError(
					ErrorConstants.FAILED_DATA_PROCESS_CLOSED_ORDERS)+SOCConstants.NEW_LINE+se.getMessage()));
			throw new SOCException(
					ErrorMessageReader.getError(
							ErrorConstants.FAILED_DATA_PROCESS_CLOSED_ORDERS),se);
		}
		finally
		{
			try {

				if(rsClosedOrders!=null)
				{
					rsClosedOrders.close();
				}
			}
			catch (SQLException sqle) 
			{
				d_fileWriter.write(d_logFileName, SOCUtility.writeLogMessage(ErrorMessageReader.getError(
						ErrorConstants.FAILED_CLOSE_RESULTSET_TBL_STAGING_CLOSED_ORDER_LINES)+SOCConstants.NEW_LINE+sqle.getMessage()));
				throw new SOCException(
						ErrorMessageReader.getError(
								ErrorConstants.FAILED_CLOSE_RESULTSET_TBL_STAGING_CLOSED_ORDER_LINES),sqle);
			}
			try {

				if(closedOrderStmt!=null)
				{
					closedOrderStmt.close();
				}
			}
			catch (SQLException sqle) 
			{
				d_fileWriter.write(d_logFileName, SOCUtility.writeLogMessage(ErrorMessageReader.getError(
						ErrorConstants.FAILED_CLOSE_STATEMENT_TBL_STAGING_CLOSED_ORDER_LINES)+SOCConstants.NEW_LINE+sqle.getMessage()));
				throw new SOCException(
						ErrorMessageReader.getError(
								ErrorConstants.FAILED_CLOSE_STATEMENT_TBL_STAGING_CLOSED_ORDER_LINES),sqle);
			}			
		}
	}
	
	private SOCClosedOrderLine getOrderLine(ResultSet rsClosedOrders) throws SOCException
	{
		SOCClosedOrderLine closedOrderLine = new SOCClosedOrderLine();
		long orderNum = -1;
		try
		{
			orderNum=rsClosedOrders.getLong("ORDER_NUMBER");
			closedOrderLine.setOrderNumber(String.valueOf(orderNum));
			
			closedOrderLine.setHeaderId(String.valueOf(rsClosedOrders.getLong("HEADER_ID")));
			
			Timestamp orderDate = rsClosedOrders.getTimestamp("ORDERED_DATE");
			String orderedDate = null;
			if(orderDate!=null)
			{
				orderedDate = SOCUtility.formatDate(orderDate);
				closedOrderLine.setOrderDate(orderedDate);
			}
						
			closedOrderLine.setLineCatCode(rsClosedOrders.getString("LINE_CATEGORY_CODE"));
			closedOrderLine.setLineTypeId(String.valueOf(rsClosedOrders.getInt("LINE_TYPE_ID")));
			closedOrderLine.setLineId(String.valueOf(rsClosedOrders.getLong("LINE_ID")));
			closedOrderLine.setLineNumber(String.valueOf(rsClosedOrders.getInt("LINE_NUMBER")));
			closedOrderLine.setPartyID(String.valueOf(rsClosedOrders.getLong("PARTY_ID")));
			closedOrderLine.setCustEmailID(rsClosedOrders.getString("EMAIL_ADDRESS"));
			closedOrderLine.setSalesRepId(String.valueOf(rsClosedOrders.getLong("SALESREP_ID")));
			closedOrderLine.setSalesRepName(rsClosedOrders.getString("SALESREP_NAME"));
			closedOrderLine.setSellingStore(rsClosedOrders.getString("SELLING_STORE"));			
			closedOrderLine.setTaxExemptionType(rsClosedOrders.getString("TAX_EXEMPTION_TYPE"));
			closedOrderLine.setEmployyBadge(rsClosedOrders.getString("EMPLOYEE_BADGE_NUM"));
			closedOrderLine.setHeaderInvoiceToOrgId(String.valueOf(rsClosedOrders.getInt("HEADER_INVOICE_TO_ORG_ID")));
			closedOrderLine.setHeaderShipToOrgId(String.valueOf(rsClosedOrders.getInt("HEADER_SHIP_TO_ORG_ID")));
			closedOrderLine.setHeaderPackingInstructions(rsClosedOrders.getString("HEADER_PACKING_INSTRUCTIONS"));
			closedOrderLine.setHeaderShippingInstructions(rsClosedOrders.getString("HEADER_SHIPPING_INSTRUCTIONS"));
			closedOrderLine.setHeaderShipToKey(rsClosedOrders.getString("HEADER_SHIP_TO_KEY"));
			closedOrderLine.setHeaderBillToKey(rsClosedOrders.getString("HEADER_BILL_TO_KEY"));			
			closedOrderLine.setLineShipToKey(rsClosedOrders.getString("LINE_SHIP_TO_KEY"));
			closedOrderLine.setLineBilltoKey(rsClosedOrders.getString("LINE_BILL_TO_KEY"));
			closedOrderLine.setShippingMethodCode(rsClosedOrders.getString("SHIPPING_METHOD_CODE"));			
			
			Timestamp scheduleShipDate = rsClosedOrders.getTimestamp("SCHEDULE_SHIP_DATE");
			if(scheduleShipDate!=null)
			{
				closedOrderLine.setScheduleShipDate(SOCUtility.formatDate(scheduleShipDate));
			}
						
			Timestamp promiseDate = rsClosedOrders.getTimestamp("PROMISE_DATE");
			if(promiseDate!=null)
			{
				closedOrderLine.setPromiseDate((SOCUtility.formatDate(promiseDate)));
			}
			
			closedOrderLine.setLineShipToOrgId(String.valueOf(rsClosedOrders.getInt("LINE_SHIP_TO_ORG_ID")));
			closedOrderLine.setLineShipFromOrgId(String.valueOf(rsClosedOrders.getInt("LINE_SHIP_FROM_ORG_ID")));
			closedOrderLine.setTntDeliveryTimeslot(rsClosedOrders.getString("TNT_DELIVERY_TIMESLOT"));
			closedOrderLine.setLinePackingInstructions(rsClosedOrders.getString("LINE_PACKING_INSTRUCTIONS"));
			closedOrderLine.setLineShippingInstructions(rsClosedOrders.getString("LINE_SHIPPING_INSTRUCTIONS"));
			closedOrderLine.setUnitSellingPrice(rsClosedOrders.getBigDecimal("UNIT_SELLING_PRICE"));
			closedOrderLine.setUnitListPrice(rsClosedOrders.getBigDecimal("UNIT_LIST_PRICE"));
			closedOrderLine.setPricingQty(rsClosedOrders.getInt("PRICING_QUANTITY"));
			closedOrderLine.setOrderedQty(rsClosedOrders.getInt("ORDERED_QUANTITY"));
			closedOrderLine.setSubinventory(rsClosedOrders.getString("SUBINVENTORY"));
			closedOrderLine.setTaxValue(rsClosedOrders.getBigDecimal("TAX_VALUE"));
			closedOrderLine.setGiftRegLineNum(rsClosedOrders.getString("GIFT_REG_LINE_NUM"));
			closedOrderLine.setGiftRegNum(rsClosedOrders.getString("GIFT_REG_NUM"));
			closedOrderLine.setLineReturnContext(rsClosedOrders.getString("LINE_RETURN_CONTEXT"));
			closedOrderLine.setLineReturnReasonCode(rsClosedOrders.getString("LINE_RETURN_REASON_CODE"));
			closedOrderLine.setLineRefLineId(String.valueOf(rsClosedOrders.getInt("LINE_REF_LINE_ID")));
			closedOrderLine.setLineRefHeaderId(String.valueOf(rsClosedOrders.getInt("LINE_REF_HEADER_ID")));
			closedOrderLine.setLineReturnAttr1(rsClosedOrders.getString("LINE_RETURN_ATTR1"));
			closedOrderLine.setLineReturnAttr2(rsClosedOrders.getString("LINE_RETURN_ATTR2"));
			closedOrderLine.setLineReturnAttr3(rsClosedOrders.getString("LINE_RETURN_ATTR3"));
			closedOrderLine.setLineReturnAttr4(rsClosedOrders.getString("LINE_RETURN_ATTR4"));
			closedOrderLine.setLineReturnAttr5(rsClosedOrders.getString("LINE_RETURN_ATTR5"));
			closedOrderLine.setLineServiceRefLineId(String.valueOf(rsClosedOrders.getInt("LINE_SERVICE_REF_ID")));
			closedOrderLine.setInventoryItemId(rsClosedOrders.getString("LINE_RMA_DETAILS"));
			closedOrderLine.setSalesRepId(String.valueOf(rsClosedOrders.getInt("INVENTORY_ITEM_ID")));
			closedOrderLine.setItemSKU(rsClosedOrders.getString("ITEM_SKU"));
			closedOrderLine.setItemType(rsClosedOrders.getString("ITEM_TYPE"));
			closedOrderLine.setItemDescription(rsClosedOrders.getString("ITEM_DESCRIPTION"));
			closedOrderLine.setItemCatalogGroupId(String.valueOf(rsClosedOrders.getInt("ITEM_CATALOG_GROUP_ID")));
			closedOrderLine.setItemCategory(rsClosedOrders.getString("ITEM_CATEGORY"));
			closedOrderLine.setPrimaryUnitofMeasure(rsClosedOrders.getString("PRIMARY_UNIT_OF_MEASURE"));
			closedOrderLine.setOrgName(rsClosedOrders.getString("ORG_NAME"));
			closedOrderLine.setTimeZone(rsClosedOrders.getString("TIME_ZONE"));
			closedOrderLine.setLocationId(String.valueOf(rsClosedOrders.getInt("LOCATION_ID")));
			closedOrderLine.setCashReceiptId(String.valueOf(rsClosedOrders.getInt("CASH_RECEIPT_ID")));
			
			Timestamp cashReceiptDate = rsClosedOrders.getTimestamp("CASH_RECEIPT_DATE");
			
			if(cashReceiptDate!=null)
			{
				closedOrderLine.setCashReceiptDate(SOCUtility.formatDate(cashReceiptDate));
			}
		
			closedOrderLine.setOperator(rsClosedOrders.getString("OPERATOR"));
			closedOrderLine.setTerminal(rsClosedOrders.getString("TERMINAL"));
			closedOrderLine.setPosTxNum(rsClosedOrders.getString("POS_TX_NUM"));
			closedOrderLine.setPosStoreNum(rsClosedOrders.getString("POS_STORE_NUM"));
			closedOrderLine.setTaxProvince(rsClosedOrders.getString("TAX_PROVINCE"));
			closedOrderLine.setGstTax(rsClosedOrders.getBigDecimal("GSTTAX"));
			closedOrderLine.setGstPercent(rsClosedOrders.getBigDecimal("GSTPERCENT"));
			closedOrderLine.setPstTax(rsClosedOrders.getBigDecimal("PSTTAX"));
			closedOrderLine.setPstPercent(rsClosedOrders.getBigDecimal("PSTPERCENT"));		
			closedOrderLine.setHstTax(rsClosedOrders.getBigDecimal("HSTTAX"));
			closedOrderLine.setHstPercent(rsClosedOrders.getBigDecimal("HSTPERCENT"));
			closedOrderLine.setDeliveryId(String.valueOf(rsClosedOrders.getInt("DELIVERY_ID")));	
			closedOrderLine.setLineStatus(rsClosedOrders.getString("LINE_STATUS"));
						
		}
		catch (SQLException sqle)
		{
			sqle.printStackTrace();
			d_fileWriter.write(d_logFileName, SOCUtility.writeLogMessage(ErrorMessageReader.getError(
					ErrorConstants.FAILED_RECORD_PROCESS_TBL_STAGING_CLOSED_ORDER_LINES)+orderNum+SOCConstants.NEW_LINE+sqle.getMessage()));
			throw new SOCException(
					ErrorMessageReader.getError(
							ErrorConstants.FAILED_RECORD_PROCESS_TBL_STAGING_CLOSED_ORDER_LINES) + orderNum ,sqle);
		}
		
		return closedOrderLine;
	}
	
	private void processOrder(ArrayList<SOCClosedOrderLine> orderLines,long orderNumber) throws SOCException
	{
		ArrayList<SOCClosedOrderLine> closedLineAdjustmentLines = new ArrayList<SOCClosedOrderLine>();
		ArrayList<SOCClosedOrderLine> returnLines = new ArrayList<SOCClosedOrderLine>();
		HashMap<Long,SOCClosedOrderLine> salesLinesMap = new HashMap<Long,SOCClosedOrderLine>();
		
		if(orderLines!=null && orderLines.size()>0)
		{
			Iterator<SOCClosedOrderLine> iter=orderLines.iterator();
    		while(iter.hasNext())
	    	{
    			SOCClosedOrderLine line = iter.next();
    			int lineTypeId = Integer.parseInt(line.getLineTypeId());
    			if(lineTypeId==1006 || lineTypeId==1007)
    			{
    				returnLines.add(line);
    			}
    			else if(lineTypeId==1005) 
    			{
    				if(line.getLineReturnAttr5()!=null)
    				{
    					closedLineAdjustmentLines.add(line);
    				}
    				else if(line.getLineReturnAttr4()!=null || line.getLineReturnAttr2()!=null )
    				{
    					returnLines.add(line);
    				}
    				else
    				{
    					salesLinesMap.put(Long.parseLong(line.getLineId()),line);
    				}
    			}
    			else{
    				salesLinesMap.put(Long.parseLong(line.getLineId()),line);
    			}
			}    		    		
		}
				
		SOCOrder order = null;
		
		if(salesLinesMap.size()>0)
		{
			associateClosedLinePriceAdjustments(orderNumber,salesLinesMap,closedLineAdjustmentLines);
			associateReturnLines(orderNumber,salesLinesMap,returnLines);
			
			order = createOrder(orderNumber,salesLinesMap);
			if(order!=null)
			{
				writeClosedOrderXML(orderNumber,order);
			}
		}
		else
		{
			statisticsHandler.addMessages(orderNumber, d_batchNum, SOCConstants.INFO, SOCConstants.MESSAGE_PROCESSING_CLOSED_ORDER_WITH_NO_SALES_LINE,"");
			notConvertedOrdersList.add(orderNumber);
			d_ordersNotConverted++;
		}
	}
	
	private void associateClosedLinePriceAdjustments(long orderNum,HashMap<Long,SOCClosedOrderLine> salesLinesMap,ArrayList<SOCClosedOrderLine> closedLineAdjustmentLines) throws SOCException 
	{
		Iterator<SOCClosedOrderLine> iter=closedLineAdjustmentLines.iterator();
		SOCClosedOrderLine closedLinePriceAdjustment = null;
		while(iter.hasNext())
    	{
			closedLinePriceAdjustment = iter.next();
			BigDecimal priceAdjt =  closedLinePriceAdjustment.getUnitSellingPrice();
			
			SOCClosedOrderLine salesLine = salesLinesMap.get(Long.parseLong(closedLinePriceAdjustment.getLineReturnAttr5()));
			if(salesLine!=null)
			{
				BigDecimal origPrice =salesLine.getUnitSellingPrice();
				BigDecimal adjustedPrice = SOCUtility.getDifference(origPrice,priceAdjt);
				
				BigDecimal priceAdjtTaxValue = closedLinePriceAdjustment.getTaxValue();
				BigDecimal origTaxValue = salesLine.getTaxValue();			
				BigDecimal adjustedTaxValue = SOCUtility.getDifference(origTaxValue,priceAdjtTaxValue);
				
				BigDecimal priceAdjtGstTax = closedLinePriceAdjustment.getGstTax();
				BigDecimal origGstTax = salesLine.getGstTax();
				BigDecimal adjustedGstTax  = SOCUtility.getDifference(origGstTax,priceAdjtGstTax);
				
				BigDecimal priceAdjtPstTax = closedLinePriceAdjustment.getPstTax();
				BigDecimal origPstTax =salesLine.getPstTax();
				BigDecimal adjustedPstTax = SOCUtility.getDifference(origPstTax,priceAdjtPstTax);
				
				BigDecimal priceAdjtHstTax = closedLinePriceAdjustment.getHstTax();
				BigDecimal origHstTax = salesLine.getHstTax();
				BigDecimal adjustedHstTax = SOCUtility.getDifference(origHstTax,priceAdjtHstTax);
				
				salesLine.setUnitSellingPrice(adjustedPrice);
				salesLine.setTaxValue(adjustedTaxValue);
				salesLine.setGstTax(adjustedGstTax);
				salesLine.setPstTax(adjustedPstTax);
				salesLine.setHstTax(adjustedHstTax);
			}
			else
			{
				statisticsHandler.addMessages(orderNum, d_batchNum, SOCConstants.WARNING, SOCConstants.MESSAGE_PROCESSING_CLOSED_PRICE_ADJUSTMENT_WITH_NO_SALES_LINE,closedLinePriceAdjustment.getLineId());
			}
    	}
	}
	
	private void associateReturnLines(long orderNum,HashMap<Long,SOCClosedOrderLine> salesLinesMap,ArrayList<SOCClosedOrderLine> returnLines) throws SOCException
	{
		Iterator<SOCClosedOrderLine> iter=returnLines.iterator();
		SOCClosedOrderLine returnLine = null;
		SOCClosedOrderLine salesLine  = null;
		boolean saleLineFound= false;
		while(iter.hasNext())
    	{
			returnLine = iter.next();
			String returnAttr2=returnLine.getLineReturnAttr2();
			String returnAttr4=returnLine.getLineReturnAttr4();
			if(returnAttr2!=null)
			{
				salesLine= salesLinesMap.get(Long.parseLong(returnAttr2));
			}
			else if(returnAttr4!=null)
			{
				salesLine= salesLinesMap.get(Long.parseLong(returnAttr4));				
			}
			if(salesLine!=null)
			{
				if(salesLine.getLineStatus().equals(returnLine.getLineStatus()))
				{
					saleLineFound = true;
				}
			}
			
			if(saleLineFound)
			{
				salesLine.setIsReturned(true);
				salesLine.setReturnLine(returnLine);
			}
			else
			{
				if(!"CANCELLED".equals(returnLine.getLineStatus()))
				{
					statisticsHandler.addMessages(orderNum, d_batchNum, SOCConstants.WARNING, SOCConstants.MESSAGE_PROCESSING_RETURN_LINE_WITH_NO_SALES_LINE,returnLine.getLineId());
				}
			}
			saleLineFound= false;
    	}
		
	}
	
	private SOCOrder createOrder(long orderNum,HashMap<Long,SOCClosedOrderLine> salesLinesMap) throws SOCException
	{
		SOCOrder order = null;
		ArrayList<SOCClosedOrderLine> doNotConvertLines = new ArrayList<SOCClosedOrderLine>();
		
		if(salesLinesMap!=null && salesLinesMap.size()>0)
		{
			Iterator<SOCClosedOrderLine> iterator = salesLinesMap.values().iterator();
			order = new SOCOrder();
			SOCOrderExtn orderExtn = new SOCOrderExtn();
			SOCOrderNotes orderNotes = new SOCOrderNotes();
			SOCOrderLines orderLines = new SOCOrderLines(orderNum,statisticsHandler,d_batchNum);
			SOCOrderPriceInfo orderPriceInfo = new SOCOrderPriceInfo();
		//	    SOCOrderPersonalInfoBillTo infoBillTo = new SOCOrderPersonalInfoBillTo();
			SOCOrderPersonalInfoShipTo infoShipTo = new SOCOrderPersonalInfoShipTo();
		//		SOCOrderPersonalInfoSoldTo infoSoldTo = new SOCOrderPersonalInfoSoldTo();
			SOCHeaderCharges headerCharges = new SOCHeaderCharges();
			SOCOrderLineCharges lineCharges = new SOCOrderLineCharges();
			
			boolean orderInfoProcessed = false;
			while(iterator.hasNext())
			{
				SOCClosedOrderLine line = iterator.next();
				
				if(!orderInfoProcessed){
					order=populateOrder(line);
					
					orderExtn.setExtnHBCAssociateID(line.getEmployyBadge());
					
					orderNotes=populateOrderNotes(line);					
			//		infoBillTo=populateInfoBillTo(line);
					infoShipTo=populateOrderInfoShipTo(line);
					orderInfoProcessed=true;
				}
				
				String itemType = line.getItemType();
				if(SOCConstants.ALL.equals(itemType))
				{
					SOCHeaderCharge headerCharge = new SOCHeaderCharge();
					String sku = line.getItemSKU();
					BigDecimal unitSellingPrice = line.getUnitSellingPrice();
					int quantity =line.getOrderedQty();
					BigDecimal chargeAmt = quantity>0?unitSellingPrice.multiply(new BigDecimal(quantity)).setScale(2):unitSellingPrice.setScale(2);
					// remove leading zeroes from sku
					if(SOCUtility.isNumber(sku))
					{
						int skuNumber = Integer.parseInt(sku);
						sku = String.valueOf(skuNumber);
					}
					String chargeName = SOCChargeNames.getHeaderChargeMap().get(sku).getChargeName();
					headerCharge.setChargeAmount(chargeAmt);
					headerCharge.setChargeName(chargeName);
					headerCharges.addHeaderCharge(headerCharge);					
				}
			
				else if(isMCFLine(itemType))
				{
					SOCOrderLine orderLine = new SOCOrderLine();
					SOCOrderLineItem lineItem = new SOCOrderLineItem();	
					SOCOrderLinePriceInfo linePriceInfo = new SOCOrderLinePriceInfo();
					SOCOrderPersonalInfoShipTo lineInfoShipTo = new SOCOrderPersonalInfoShipTo();
					SOCOrderNotes lineNotes = new SOCOrderNotes();
					SOCOrderLineExtn lineExtn = new SOCOrderLineExtn();
					SOCOrderLineStatus lineStatus = new SOCOrderLineStatus();
					SOCOrderLineTaxes lineTaxes = new SOCOrderLineTaxes();
					SOCOrderLineSchedule lineschedule = new SOCOrderLineSchedule();
					
					orderLine = populateOrderLine(line);		
					
					lineItem=populateLineItem(line);
					linePriceInfo=populateLinePriceInfo(line);					
					lineInfoShipTo=populateLineInfoShipTo(line);					
					lineNotes = populateNotes(line);					
					lineExtn=populateLineExtn(line);
					lineStatus=populateOrderLineStatus(line);
					lineTaxes = populateLineTaxes(line);
					lineCharges = populateLineCharges(line);
					lineschedule = populateSOCOrderLineSchedule(line); 
					
					orderLine.setLineItem(lineItem);
					orderLine.setLineCharges(lineCharges);
					orderLine.setLinePriceInfo(linePriceInfo);
					orderLine.setInfoShipTo(lineInfoShipTo);
					orderLine.setLineNotes(lineNotes);
					orderLine.setLineExtn(lineExtn);
					lineStatus.setLineschedule(lineschedule);
					orderLine.setLineStatus(lineStatus);
					orderLine.setLineTaxes(lineTaxes);
					orderLine.setLineTotal();
					orderLine.setItemCategory(line.getItemCategory());
//					orderLine.setLineschedule(lineschedule);
					orderLines.addOrderLine(orderLine);
					
				}
				else if(SOCConstants.SVG.equals(itemType))
				{
					SOCOrderLineSalvage salvageOrderLine = new SOCOrderLineSalvage();
				
					salvageOrderLine = populateSalvageOrderLine(line);	
					orderLines.addSalvageOrderLine(salvageOrderLine);
					
				}
				else if(isInvalidLine(itemType))
				{
					statisticsHandler.addMessages(orderNum, d_batchNum, SOCConstants.INFO, SOCConstants.MESSAGE_PROCESSING_LINE_WITH_INVALID_ITEM_TYPE+itemType ,line.getLineId());
					doNotConvertLines.add(line);
				}
			}
			orderLines.filterOrderLineList();
			orderLines.filterSalvageOrderLineList();
			orderLines.attachSalvageWithDelivery();
			orderLines.filterWTYOrderLines();
			
		//	infoSoldTo=populateOrderInfoSoldTo(orderLines);
		//	order.setInfoSoldTo(infoSoldTo);
			order.setOrderNotes(orderNotes);
			order.setOrderExtn(orderExtn);
			order.setOrderPriceInfo(orderPriceInfo);
		//	order.setInfoBillTo(infoBillTo);
			order.setInfoShipTo(infoShipTo);
			order.setHeaderCharges(headerCharges);
			order.setOrderLines(orderLines);
			order.setHeaderChargeTotal();
			order.setTotalTax();
			order.setTotalLines();
			order.setOrderTotal();
			order.setOrderShipToKey();
		}
		
		return order;
	}
	
	private boolean isMCFLine(String itemType)
	{
		boolean result = false;		
		if(CofiToMcfLinesItemTypes.getItemType(itemType)!=null)
		{
			result = true;
		}
		return result;
	}
	
	private boolean isInvalidLine(String itemType)
	{
		boolean result = false;
		if(InvalidItemTypes.getItemType(itemType)!=null)
		{
			result = true;
		}
		return result;
	}
	
	public int getRecordsFetched()
	{
		return d_recordsFetched;
	}
	
	public int getOrdersNotConverted()
	{
		return d_ordersNotConverted;
	}
	
	public int getCountXMLCreated()
	{
		return d_xmlCounter;
	}
	
	private void writeClosedOrderXML(long orderNumber,SOCOrder order) throws SOCException
	{
		int childDir = getChildDirectory();
		File childDirRef= new File(d_xmlDirectory+SOCConstants.DELIMITER+childDir);
    	if (!childDirRef.exists())
        {
    		childDirRef.mkdir();    	
    	}
		
		String orderRec = order.toString();
		if(orderRec.length()>0)
		{
			String xmlFileName= childDirRef.getAbsolutePath()+SOCConstants.DELIMITER +SOCConstants.CLOSED_SALES_ORDER_XML_FILE+order.getOrderNum()+SOCConstants.XML_FILE_EXTN;
			d_fileWriter.write(xmlFileName,orderRec);    	
			convertedOrdersList.add(orderNumber);
			d_fileWriter.closeFile(xmlFileName);
			d_xmlCounter++;
		}
		else
		{
			d_ordersNotConverted++;
			notConvertedOrdersList.add(orderNumber);
			statisticsHandler.addMessages(orderNumber, d_batchNum, SOCConstants.INFO, SOCConstants.MESSAGE_PROCESSING_CLOSED_ORDER_WITH_NO_SALES_LINE,"");			
		}
	}

    private int getChildDirectory()
    {
    	int result = 0;
    	int division = ((d_xmlCounter+1)/SOCConstants.MAXIMUM_FILE_COUNT);
    	int reminder = ((d_xmlCounter+1)%SOCConstants.MAXIMUM_FILE_COUNT);
    	
    	if(reminder>0)
    	{
    		result = division+1;
    	}
    	else
    	{
    		result = division;
    	}
    	
    	return result;
    }
    
    private SOCOrderLineItem populateLineItem(SOCClosedOrderLine line)
    {
    	SOCOrderLineItem lineItem = new SOCOrderLineItem();
    	
    	String itemType = line.getItemType();
    	
    	if("DEL".equals(itemType))
    	{
    		lineItem.setItemID(SOCConstants.MCF_DEL_SKU);
    	}	
    	else
    	{
    		lineItem.setItemID(line.getItemSKU());
    	}
    	
		lineItem.setItemShortDesc(line.getItemDescription());
		String subinventory = line.getSubinventory();
		if(subinventory!=null && SOCConstants.FLOORMODEL.equals(subinventory))
		{
			lineItem.setProductClass(SOCConstants.AS_IS);
		}
		lineItem.setProductLine(line.getItemCatalogGroupId());
		
		String uom= line.getPrimaryUnitofMeasure();
		
		if(uom!=null && itemType!=null)
		{
			if(("WTY".equals(itemType)|| "WRFEE".equals(itemType)))
			{
				lineItem.setUnitOfMeasure(SOCConstants.DAYS);
			}
			else if("DEL".equals(itemType) || "SVG".equals(itemType))
			{
				lineItem.setUnitOfMeasure(SOCConstants.MIN);
			}
			else
			{
				lineItem.setUnitOfMeasure(uom);
			}
			
		}
		
    	return lineItem;
    }
    
    private SOCOrderLineCharges populateLineCharges(SOCClosedOrderLine line)
    {
    	SOCOrderLineCharges lineCharges = new SOCOrderLineCharges();
    	
    	SOCOrderLineCharge lineCharge = null;
    	
    	BigDecimal unitSellingPrice = line.getUnitSellingPrice();
    	BigDecimal unitListPrice = line.getUnitListPrice();
    	int quantity = line.getOrderedQty();
    	
    	if(unitListPrice.compareTo(unitSellingPrice)==1)
    	{
    		lineCharge = new SOCOrderLineCharge();
    		lineCharge.setChargeName(SOCConstants.DISCOUNT);
    		lineCharge.setChargeCategory(SOCConstants.DISCOUNT);
    		BigDecimal chargeAmt = (unitListPrice.subtract(unitSellingPrice)).multiply(new BigDecimal(quantity)).setScale(2);
    		lineCharge.setChargeAmount(chargeAmt.toString());
    		lineCharges.addOrderLineCharge(lineCharge);
    	}
    	else if (unitSellingPrice.compareTo(unitListPrice)==1)
    	{
    		lineCharge = new SOCOrderLineCharge();
    		lineCharge.setChargeName(SOCConstants.CHARGE);
    		lineCharge.setChargeCategory(SOCConstants.CHARGE);
    		BigDecimal chargeAmt = (unitSellingPrice.subtract(unitListPrice)).multiply(new BigDecimal(quantity)).setScale(2);
    		lineCharge.setChargeAmount(chargeAmt.toString());
    		lineCharges.addOrderLineCharge(lineCharge);
    	}
    	return lineCharges;
    }
    
    private SOCOrderLinePriceInfo populateLinePriceInfo(SOCClosedOrderLine line)
    {
    	SOCOrderLinePriceInfo linePriceInfo = new SOCOrderLinePriceInfo();
    	linePriceInfo.setActualPricingQty(String.valueOf(line.getOrderedQty()));
		linePriceInfo.setListPrice(line.getUnitListPrice().toString());
		linePriceInfo.setOrderedPricingQty(line.getOrderedQty());
		linePriceInfo.setRetailPrice(line.getUnitListPrice());
		linePriceInfo.setUnitPrice(line.getUnitSellingPrice());
		
		return linePriceInfo;
    }
    
    private SOCOrderPersonalInfoShipTo populateLineInfoShipTo(SOCClosedOrderLine line)
    {
    	SOCOrderPersonalInfoShipTo lineInfoShipTo = new SOCOrderPersonalInfoShipTo();
		lineInfoShipTo.setAddressID(line.getPartyID());
		lineInfoShipTo.setPersonID(line.getLineShipToOrgId());
		return lineInfoShipTo;
    }
    
    private SOCOrderNotes populateNotes(SOCClosedOrderLine line)
    {
    	SOCOrderNotes lineNotes = new SOCOrderNotes();
    	String shippingInstructions = line.getLineShippingInstructions();
		String packgingInstructions = line.getLinePackingInstructions();
		SOCOrderNote lineNote = null;
		if(shippingInstructions!=null &&  shippingInstructions.trim().length()>0)
		{
			lineNote = new SOCOrderNote();
			lineNote.setNoteText(shippingInstructions);
			lineNote.setReasonCode(SOCConstants.CLOSED_ORDER_SHIPPING_NOTE);
			lineNotes.addOrderNote(lineNote);
		}
		
		if(packgingInstructions!=null && packgingInstructions.trim().length()>0)
		{
			lineNote = new SOCOrderNote();
			lineNote.setNoteText(packgingInstructions);
			lineNote.setReasonCode(SOCConstants.CLOSED_ORDER_PACKAGING_NOTE);
			lineNotes.addOrderNote(lineNote);
		}
		
		return lineNotes;
    }
    
    private SOCOrderLineExtn populateLineExtn(SOCClosedOrderLine line)
    {
    	SOCOrderLineExtn lineExtn = new SOCOrderLineExtn();
    	lineExtn.setExtnGiftRegNum(line.getGiftRegNum());
		lineExtn.setExtnGiftRegLineNum(line.getGiftRegLineNum());
		lineExtn.setExtnPOSTxnNum(line.getPosTxNum());
		lineExtn.setExtnPOSStoreNum(line.getPosStoreNum());
		lineExtn.setExtnPOSRegNum(line.getTerminal());
		lineExtn.setExtnTaxProvince(line.getTaxProvince());
		lineExtn.setExtnPOSTenderDT(line.getCashReceiptDate());
		HashMap<String,String> storeProvinceMap =SOCPOSProvince.getPOsStoreNumProvinceMap();
		if(storeProvinceMap!=null)
		{	
			String posProvince = storeProvinceMap.get(line.getPosStoreNum());
			lineExtn.setExtnPOSProvince(posProvince);
    	}
		String subinventory = line.getSubinventory();
		if(subinventory!=null && (SOCConstants.FLOORMODEL.equals(subinventory) || SOCConstants.AS_IS.equals(subinventory)))
		{
			lineExtn.setExtnIsOpenBoxItem(SOCConstants.FLAG_Y);
		}
		else
		{
			lineExtn.setExtnIsOpenBoxItem(SOCConstants.FLAG_N);
		}
		
		return lineExtn;
    }
    
    private SOCOrderLineStatus populateOrderLineStatus(SOCClosedOrderLine line)
    {
    	SOCOrderLineStatus lineStatus = new SOCOrderLineStatus();
    	String shippingMethod=line.getShippingMethodCode();
    
		if(shippingMethod==null)
		{
			shippingMethod=SOCConstants.DEFAULT_SHIPPING_METHOD_CLOSED_SALES;
		}
		if(Integer.parseInt(line.getDeliveryId())!=0)
		{
			lineStatus.setReleaseNo(line.getDeliveryId());
		}
		String orderStatus = ClosedOrderStatus.getMCFOrderStatus(shippingMethod);
		if(orderStatus==null)
		{
			shippingMethod=SOCConstants.DEFAULT_SHIPPING_METHOD_CLOSED_SALES;
			orderStatus = ClosedOrderStatus.getMCFOrderStatus(shippingMethod);
		}
		lineStatus.setStatus(orderStatus);
		
		lineStatus.setStatusQty(String.valueOf(line.getOrderedQty()));
		
		return lineStatus;
    }
    
    private SOCOrderLineSchedule populateSOCOrderLineSchedule(SOCClosedOrderLine line)
    {
    	SOCOrderLineSchedule lineschedule = new SOCOrderLineSchedule();
    	lineschedule.setExpectedDeliveryDate(line.getScheduleShipDate());
    	lineschedule.setExpectedShipmentDate(line.getScheduleShipDate());
    	lineschedule.setShipByDate(SOCUtility.getDate(line.getScheduleShipDate()));
    	String shipNode = line.getOrgName();
		if(shipNode!=null && shipNode.length()>4)
		{
			shipNode = shipNode.substring(0,4);
			int storeNum = 0;
			if(SOCUtility.isNumber(shipNode))
			{
				storeNum = Integer.parseInt(shipNode);
			}
			// to do error handling if it's not a number
			lineschedule.setShipNode(String.valueOf(storeNum));
			lineschedule.setProcureFromNode(String.valueOf(storeNum));
		}
		
		String tntDeliveryTS = line.getTntDeliveryTimeslot();
		if(tntDeliveryTS==null || SOCConstants.EMPTY_STRING.equals(tntDeliveryTS))
		{
			tntDeliveryTS="DEFAULT";
		}
		String scheduleShipDate = SOCUtility.getDate(line.getScheduleShipDate());
		if(SOCConstants.EMPTY_STRING.equals(scheduleShipDate))
		{
			lineschedule.setPromisedApptEndDate(SOCConstants.EMPTY_STRING);
			lineschedule.setPromisedApptStartDate(SOCConstants.EMPTY_STRING);
		}
		else
		{
			lineschedule.setPromisedApptEndDate(scheduleShipDate + SOCConstants.BLANK_STRING+PromiseEndDate.valueOf(tntDeliveryTS).getBeanProperty());
			lineschedule.setPromisedApptStartDate(scheduleShipDate + SOCConstants.BLANK_STRING+PromiseStartDate.valueOf(tntDeliveryTS).getBeanProperty());
		}
    	return lineschedule;
    }
    
//    private SOCOrderPersonalInfoBillTo populateInfoBillTo(SOCClosedOrderLine line)
//    {
//    	SOCOrderPersonalInfoBillTo infoBillTo = new SOCOrderPersonalInfoBillTo();
//    	infoBillTo.setAddressID(line.getHeaderInvoiceToOrgId());
//		infoBillTo.setPersonID(line.getPartyID());
//		
//		return infoBillTo;
//    }
    
    private SOCOrderPersonalInfoShipTo populateOrderInfoShipTo(SOCClosedOrderLine line)
    {
    	SOCOrderPersonalInfoShipTo orderInfoShipTo = new SOCOrderPersonalInfoShipTo();
    	orderInfoShipTo.setAddressID(line.getPartyID());
    	orderInfoShipTo.setPersonID(line.getHeaderShipToOrgId());
    	return orderInfoShipTo;
    }
    
    private SOCOrderNotes populateOrderNotes(SOCClosedOrderLine line)
    {
    	SOCOrderNotes orderNotes = new SOCOrderNotes();
    	String shippingInstructions = line.getHeaderShippingInstructions();
		String packgingInstructions = line.getHeaderPackingInstructions();
		SOCOrderNote orderNote = null;
		if(shippingInstructions!=null &&  shippingInstructions.trim().length()>0)
		{
			orderNote = new SOCOrderNote();
			orderNote.setNoteText(shippingInstructions);
			orderNote.setReasonCode(SOCConstants.CLOSED_ORDER_SHIPPING_NOTE);
			orderNotes.addOrderNote(orderNote);
		}
		
		if(packgingInstructions!=null && packgingInstructions.trim().length()>0)
		{
			orderNote = new SOCOrderNote();
			orderNote.setNoteText(packgingInstructions);
			orderNote.setReasonCode(SOCConstants.CLOSED_ORDER_PACKAGING_NOTE);
			orderNotes.addOrderNote(orderNote);
		}
		
		return orderNotes;
    }
    
    private SOCOrderLineSalvage populateSalvageOrderLine(SOCClosedOrderLine line)
    {
    	SOCOrderLineSalvage salvageOrderLine = new SOCOrderLineSalvage();
    	
    	salvageOrderLine.setItemDesc(line.getItemDescription());
    	salvageOrderLine.setItemID(line.getItemSKU());
    	salvageOrderLine.setUnitOfMeasure(line.getPrimaryUnitofMeasure());
    	BigDecimal amt = line.getUnitSellingPrice().multiply(new BigDecimal(line.getOrderedQty())).setScale(2);
    	salvageOrderLine.setUnitPrice(amt);
    	salvageOrderLine.setIsReturned(line.getIsReturned());
    	salvageOrderLine.setStatus(line.getLineStatus());
    	salvageOrderLine.setLineId(line.getLineId());
    	salvageOrderLine.setIsHSTEligible(HSTEligible(line));
    	BigDecimal gstTax = line.getGstTax();
		BigDecimal pstTax = line.getPstTax();
		BigDecimal hstTax = line.getHstTax();
			
		if(HSTEligible(line))
		{
			BigDecimal taxAmt = new BigDecimal("0");
			BigDecimal taxPercentage = new BigDecimal("0");
			
			if(hstTax.compareTo(new BigDecimal("0"))==1)
			{
				taxAmt=hstTax;
				taxPercentage=line.getHstPercent();
			}
			else
			{
				if(gstTax.compareTo(new BigDecimal("0"))==1)
				{
					taxAmt = gstTax;
					taxPercentage = line.getGstPercent();
				}
				if(pstTax.compareTo(new BigDecimal("0"))==1)
				{
					taxAmt = taxAmt.add(pstTax);
					taxPercentage = taxPercentage.add(line.getPstPercent());
				}
			}
		
			if(taxAmt.compareTo(new BigDecimal("0"))==1)
			{
				salvageOrderLine.setHstTaxPercentage(taxPercentage);
				salvageOrderLine.setHstTax(taxAmt);
			}			
		}
		else
		{
			if(gstTax.compareTo(new BigDecimal("0"))==1)
			{
				salvageOrderLine.setGstTaxPercentage(line.getGstPercent());
				salvageOrderLine.setGstTax(gstTax);
			}
			
			if(pstTax.compareTo(new BigDecimal("0"))==1)
			{
				salvageOrderLine.setPstTaxPercentage(line.getPstPercent());
				salvageOrderLine.setPstTax(pstTax);
			}
			
			if(hstTax.compareTo(new BigDecimal("0"))==1)
			{
				salvageOrderLine.setHstTaxPercentage(line.getHstPercent());
				salvageOrderLine.setHstTax(hstTax);
			}
		}
		
    	return salvageOrderLine;
    }
    
    private SOCOrderLine populateOrderLine(SOCClosedOrderLine line)
    {
    	SOCOrderLine orderLine = new SOCOrderLine();
    	
    	orderLine.setStatus(line.getLineStatus());
    	orderLine.setLineId(line.getLineId());
    	String shippingMethod=line.getShippingMethodCode();
    	orderLine.setShippingMethod(shippingMethod);
    	orderLine.setLineItemType(line.getItemType());
    	orderLine.setUnitListPrice(line.getUnitListPrice());
    	orderLine.setServiceRefId(line.getLineServiceRefLineId());
    	orderLine.setLineCategory(line.getItemCategory());
		if(shippingMethod==null)
		{
			shippingMethod=SOCConstants.DEFAULT_SHIPPING_METHOD_CLOSED_SALES;
		}
		
		String deliveryMethod = ClosedOrderDeliveryMethod.getMCFDeliveryMethod(shippingMethod);
	
		if(deliveryMethod==null)
		{
			shippingMethod=SOCConstants.DEFAULT_SHIPPING_METHOD_CLOSED_SALES;
			deliveryMethod = ClosedOrderDeliveryMethod.getMCFDeliveryMethod(shippingMethod);
		}
	
		orderLine.setDeliveryMethod(deliveryMethod);
		if("DEL".equals(deliveryMethod))
		{
//			orderLine.setLineShipToKey(line.getLineShipToOrgId());
			orderLine.setLineShipToKey(line.getLineShipToKey());
		}
		String fulfillmentType = ClosedOrderFulfillmentType.getMCFFulfillmentType(shippingMethod);
		if(fulfillmentType==null)
		{
			shippingMethod=SOCConstants.DEFAULT_SHIPPING_METHOD_CLOSED_SALES;
			fulfillmentType = ClosedOrderFulfillmentType.getMCFFulfillmentType(shippingMethod);
		}
		orderLine.setFulfillmentType(fulfillmentType);
		
		String mcfItemType = CItemType.getMCFItemType(line.getItemType());
		orderLine.setItemGroupCode(mcfItemType);
		
		String lineType = ClosedOrderLineType.getMCFLineType(shippingMethod);
		if(lineType==null)
		{
			shippingMethod=SOCConstants.DEFAULT_SHIPPING_METHOD_CLOSED_SALES;
			lineType = ClosedOrderLineType.getMCFLineType(shippingMethod);
		}
		orderLine.setLineType(lineType);
		
		orderLine.setMinShipByDate(line.getScheduleShipDate());
		orderLine.setOrderedQty(String.valueOf(line.getOrderedQty()));
		orderLine.setOrgOrderedQty(String.valueOf(line.getOrderedQty()));
		
		String tntDeliveryTS = line.getTntDeliveryTimeslot();
		if(tntDeliveryTS==null || SOCConstants.EMPTY_STRING.equals(tntDeliveryTS))
		{
			tntDeliveryTS="DEFAULT";
		}
		String scheduleShipDate = SOCUtility.getDate(line.getScheduleShipDate());
		if(SOCConstants.EMPTY_STRING.equals(scheduleShipDate))
		{
			orderLine.setPromisedEndDate(SOCConstants.EMPTY_STRING);
			orderLine.setPromisedStartDate(SOCConstants.EMPTY_STRING);
		}
		else
		{
			orderLine.setPromisedEndDate(scheduleShipDate + SOCConstants.BLANK_STRING+PromiseEndDate.valueOf(tntDeliveryTS).getBeanProperty());
			orderLine.setPromisedStartDate(scheduleShipDate + SOCConstants.BLANK_STRING+PromiseStartDate.valueOf(tntDeliveryTS).getBeanProperty());
		}
		orderLine.setReqDeliveryDate(line.getPromiseDate());
		orderLine.setReqShipDate(line.getScheduleShipDate());
		
		String shipNode = line.getOrgName();
		if(shipNode!=null && shipNode.length()>4)
		{
			shipNode = shipNode.substring(0,4);
			int storeNum = 0;
			if(SOCUtility.isNumber(shipNode))
			{
				storeNum = Integer.parseInt(shipNode);
			}
			// to do error handling if it's not a number
			orderLine.setShipNode(String.valueOf(storeNum));
		}	
		orderLine.setShipToID(line.getPartyID());		
		orderLine.setTimeZone(line.getTimeZone());
		orderLine.setIsReturned(line.getIsReturned());
    	return orderLine;
    }
    
    private SOCOrder populateOrder(SOCClosedOrderLine line)
    {
    	SOCOrder order = new SOCOrder();
    	order.setBillToID(line.getPartyID());
//		order.setBuyerUserId(line.getPartyID());
//		order.setBillToKey(line.getHeaderInvoiceToOrgId());
		order.setBillToKey(line.getHeaderBillToKey());
		order.setHeaderShipToKey(line.getHeaderShipToKey());
		order.setHeaderShipToOrgId(line.getHeaderShipToOrgId());
		order.setCustContactID(line.getPartyID());
		order.setCustEmailID(line.getCustEmailID());
		order.setEnteredBy(line.getSalesRepName());
		order.setOrderDate( line.getOrderDate());
		order.setOrderName(String.valueOf(d_batchNum));
		order.setOrderNum(line.getOrderNumber());
		order.setSellerOrgCode(line.getSellingStore());
		order.setShipToID(line.getPartyID());
		order.setTaxExempt(line.getTaxExemptionType());
    	return order;
    }
    
    private SOCOrderLineTaxes populateLineTaxes(SOCClosedOrderLine line)
    {
    	SOCOrderLineTaxes lineTaxes = new SOCOrderLineTaxes();
    	SOCOrderLineTax lineTax = null;
		BigDecimal gstTax = line.getGstTax();
		BigDecimal pstTax = line.getPstTax();
		BigDecimal hstTax = line.getHstTax();
		
		if(HSTEligible(line))
		{
			BigDecimal taxAmt = new BigDecimal("0");
			BigDecimal taxPercentage = new BigDecimal("0");
			
			if(hstTax.compareTo(new BigDecimal("0"))==1)
			{
				taxAmt = hstTax;
				taxPercentage = line.getHstPercent();
			}
			else
			{
				if(gstTax.compareTo(new BigDecimal("0"))==1)
				{
					taxAmt = gstTax;
					taxPercentage = line.getGstPercent();
				}
				if(pstTax.compareTo(new BigDecimal("0"))==1)
				{
					taxAmt = taxAmt.add(pstTax);
					taxPercentage = taxPercentage.add(line.getPstPercent());
				}
			}
			if(taxAmt.compareTo(new BigDecimal("0"))==1)
			{
				lineTax = new SOCOrderLineTax();
				lineTax.setChargeCategory(SOCConstants.CHARGE_NAME_PRICE);
				lineTax.setChargeName(SOCConstants.EMPTY_STRING);
				lineTax.setTaxName(SOCConstants.TAX_NAME_HST);
				lineTax.setTaxAmount(taxAmt);
				lineTax.setTaxPercentage(taxPercentage.toString());
				lineTaxes.addLineTax(lineTax);
			}			
		}
		else
		{
			if(gstTax.compareTo(new BigDecimal("0"))==1)
			{
				lineTax = new SOCOrderLineTax();
				lineTax.setChargeCategory(SOCConstants.CHARGE_NAME_PRICE);
				lineTax.setChargeName(SOCConstants.EMPTY_STRING);
				lineTax.setTaxAmount(gstTax);
				lineTax.setTaxPercentage(line.getGstPercent().toString());
				lineTax.setTaxName(SOCConstants.TAX_NAME_GST);
				lineTaxes.addLineTax(lineTax);
			}
			
			if(pstTax.compareTo(new BigDecimal("0"))==1)
			{
				lineTax = new SOCOrderLineTax();
				lineTax.setChargeCategory(SOCConstants.CHARGE_NAME_PRICE);
				lineTax.setChargeName(SOCConstants.EMPTY_STRING);
				lineTax.setTaxAmount(pstTax);
				lineTax.setTaxPercentage(line.getPstPercent().toString());
				lineTax.setTaxName(SOCConstants.TAX_NAME_PST);
				lineTaxes.addLineTax(lineTax);
			}
			
			if(hstTax.compareTo(new BigDecimal("0"))==1)
			{
				lineTax = new SOCOrderLineTax();
				lineTax.setChargeCategory(SOCConstants.CHARGE_NAME_PRICE);
				lineTax.setChargeName(SOCConstants.EMPTY_STRING);
				lineTax.setTaxAmount(hstTax);
				lineTax.setTaxPercentage(line.getHstPercent().toString());
				lineTax.setTaxName(SOCConstants.TAX_NAME_HST);
				lineTaxes.addLineTax(lineTax);
			}
		}
		return lineTaxes;
    }
    
//    private SOCOrderPersonalInfoSoldTo populateOrderInfoSoldTo(SOCOrderLines lines)
//    {
//    	SOCOrderPersonalInfoSoldTo orderInfoSoldTo = new SOCOrderPersonalInfoSoldTo();
//    	 Iterator<SOCOrderLine> iter=lines.getOrderLineList().iterator();
//    	while(iter.hasNext())
//    	{
//			SOCOrderLine line = iter.next();
//			String shippingMethod = line.getShippingMethod();
//			if(shippingMethod!=null && SOCConstants.SHIPPING_METHOD_HOME_DELIVERY_TRUCK_GROUND.equals(shippingMethod))
//			{
//				orderInfoSoldTo.setAddressID(line.getInfoShipTo().getAddressID());
//				orderInfoSoldTo.setPersonID(line.getInfoShipTo().getPersonID());
//				break;
//			}
//		}
//    	
//    	return orderInfoSoldTo;
//    }
    
    public boolean HSTEligible(SOCClosedOrderLine line)
    {
    	boolean result = false;
    	String scheduleShipDate = SOCUtility.getDate(line.getScheduleShipDate());
		String taxProvince = line.getTaxProvince();
		String cashReceiptDate = line.getCashReceiptDate();
    	
		if(taxProvince!=null && ("BC".equals(taxProvince) || "ON".equals(taxProvince)))
		{
			if(cashReceiptDate!=null && !SOCConstants.EMPTY_STRING.equals(cashReceiptDate) && SOCUtility.compareDates(cashReceiptDate,false))
			{
				if(scheduleShipDate!=null && !SOCConstants.EMPTY_STRING.equals(scheduleShipDate) && SOCUtility.compareDates(scheduleShipDate,true))
				{
					result=true;
				}
			}
		}
    	
    	return result;
    }
    
    public ArrayList<Long> getConvertedOrderList()
    {
    	return convertedOrdersList;
    }
    
    public ArrayList<Long> getNotConvertedOrderList()
    {
    	return notConvertedOrdersList;
    }
}
